package com.yunxi.service.localService.impl.otd;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunxi.bizToBaseData.service.Biz2BaseVehicleConfigDubboService;
import com.yunxi.bizToHub.pojo.OtdModelVO;
import com.yunxi.bizToHub.pojo.OtdOptionVO;
import com.yunxi.bizToHub.pojo.WeekPlanDataVO;
import com.yunxi.bizToHub.pojo.WeekPlanVO;
import com.yunxi.core.service.ServiceImplPlus;
import com.yunxi.core.util.BeanTools;
import com.yunxi.core.util.DateUtil;
import com.yunxi.core.web.DictConstant;
import com.yunxi.dao.otd.OtdOrderSoMapper;
import com.yunxi.model.otd.OtdOrderSo;
import com.yunxi.model.otd.VehicleConfigConstraint;
import com.yunxi.model.sto.VehicleOffline;
import com.yunxi.order.pojo.CustomerOrderMatchVO;
import com.yunxi.otd.pojo.OtdOrderScheduleQueryVO;
import com.yunxi.otd.pojo.OtdOrderSoVO;
import com.yunxi.service.localService.OrderVehicleService;
import com.yunxi.service.localService.VehicleProductViewService;
import com.yunxi.service.localService.otd.OtdOrderSoService;
import com.yunxi.service.localService.otd.VehicleConfigConstraintService;
import com.yunxi.service.localService.sto.VehicleOfflineService;
import com.yunxi.vehicle.pojo.VehicleProductViewVO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * <p>
 * SO生产订单 服务实现类
 * </p>
 *
 * @author XUQI
 * @since 2019-07-03
 */
@Service
public class OtdOrderSoServiceImpl extends ServiceImplPlus<OtdOrderSoMapper, OtdOrderSo> implements OtdOrderSoService {

    private static final Log logger = LogFactory.getLog(OtdOrderSoServiceImpl.class);

    @Autowired
    @Qualifier(value = "vehicleOfflineServiceImpl")
    VehicleOfflineService carService;

    @Autowired
    @Qualifier("vehicleProductViewServiceImpl")
    VehicleProductViewService productService;

    @Autowired
    @Qualifier("vehicleConfigConstraintServiceImpl")
    VehicleConfigConstraintService configConstraintService;

    @Autowired
    Biz2BaseVehicleConfigDubboService biz2baseVehicleConfigDubboService;

    @Autowired
    @Qualifier("orderVehicleServiceImpl")
    OrderVehicleService orderService;

    /**
     * 生成整车描述
     *
     * @param productCode 产品信息
     * @param customPackCode 选装包
     * @return 861（工程车型中文描述）+直客版（基础车型中文描述）+年型(对应的特征族MY_  )+市场销售(对应的特征族MS_  国别)+内 饰风格（对应的特征族NNN）+
     * 外饰风格（对应的特征族NNN）+电池容量（对应的特征族PWA）+天窗（对应的特征族UWA）+选装包个数（统计选装包个数）
     */
    public String generateCarName(String productCode, String customPackCode) {
        //查询产品信息
        VehicleProductViewVO product = productService.selectProductByCode(productCode);
        if (product == null) {
            return "";
        }
        int customPackNum = 0;
        if (!StringUtils.isEmpty(customPackCode)) {
            customPackNum = customPackCode.split(",").length;
        }

        return product.getModelName() + product.getCatalogName() + product.getYearName() + product.getCountryName()
            + product.getColorNameIn()
            + product.getColorNameOut() + product.getBatteryPackName() + productService
            .findDormerNameByCatalog(product.getCatalogCode())
            + "选装包数" + customPackNum;
    }


    /**
     * 分页查询日排程SO订单
     *
     * @param queryVO 查询VO
     * @return PageInfo
     */
    @Override
    public OtdOrderSoVO findSoOrderSchedule(OtdOrderScheduleQueryVO queryVO) {
        Map map = BeanTools.bean2map(queryVO);
        String year = queryVO.getYearMonth().substring(0, 4);
        String month = queryVO.getYearMonth().substring(4, 6);
        map.put("days", DateUtil.getDayListByMonth(Integer.valueOf(year), Integer.valueOf(month)));
//        map.put("pageNum",pageNum);
//        map.put("pageSize",pageSize);
        OtdOrderSoVO data = new OtdOrderSoVO();
        data.setTotal(baseMapper.findSoOrderScheduleCount(map));
        data.setList(baseMapper.findSoOrderSchedule(map));
//        PageHelperPlus.startPage(pageNum, pageSize);
//        List<Map<String, Object>> list = baseMapper.findSoOrderSchedule(map);
        return data;
    }

    /**
     * 查询待发送SO排产订单
     * @param orderType 订单类型
     * @param startDate 需求开始时间
     * @param endDate 需求结束时间
     * @return List<OtdOrderSo>
     */
    @Override
    public List<OtdOrderSo> findSendOrderSo(String orderType, Date startDate, Date endDate) {
        return baseMapper.findSendOrderSo(orderType, startDate, endDate);
    }

    /**
     * 删除指定日期指定数量的SO需求
     *
     * @param demandDate 需求日期
     * @param productCode 产品编码
     * @param customPackCode 选装包编码
     * @param works 工厂
     * @param orderType 订单类型
     */
    @Override
    public void deleteOverSoOrderByDay(Date demandDate, String productCode, String customPackCode, String works,
        String orderType, int num) {
        baseMapper.deleteOverSoOrderByDay(demandDate, productCode, customPackCode, works, orderType, num);
    }

    @Override
    public OtdOrderSo findOrderSoByPlanNo(String planNo) {
        LambdaQueryWrapper<OtdOrderSo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OtdOrderSo::getPlanNo, planNo);
        return baseMapper.selectOne(wrapper);
    }

    /**
     * 生成周计划接口JSON
     *
     * @param orderList 待发送so
     * @return JSON
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String generateSapJson(List<OtdOrderSo> orderList) {
        logger.debug("开始生成周计划JSON，数量：" + orderList.size());

//        ////// 约束条件
//        List<VehicleConfigConstraint> constraintsDB = configConstraintService.findEnableConfigConstraint(null);
//        if (CollectionUtils.isEmpty(constraintsDB)) {
//            throw new RuntimeException("未维护约束关系");
//        }
        ////// 约束条件
        Map<String, List<VehicleConfigConstraint>> constraintsMap = configConstraintService
            .findEnableConfigConstraintMap();

        ////// 全量工程配置
        // 全量工程配置 MAP,<key:特征值,value:特征族>
        Map<String, String> allConfigMap = biz2baseVehicleConfigDubboService.loadAllEngineeringConfig();

        /////////////////组装接口数据//////////////////
        // 周生产订单单车集合
        List<WeekPlanVO> orders = new ArrayList<>();
        // 选装包
        List<OtdOptionVO> packages = new ArrayList<>();
        // 选装包配置
        List<OtdModelVO> options = new ArrayList<>();

        //已匹配零售订单且未配车的 订货单
        Map<String, List<String>> customerMap = createWaitMatchOrder();

        // 配置识别码初始化
//        String timestamp = DateUtil.format(new Date(), "yyMMddHHmmssSSS");
//        String rd = new Random().nextInt(9999 - 1000) + 1000 + "";
//        int initPackageNo;
        // packageNoMap: 记录已添加的选装包

//        packageNoMap.put("", "10000");
        String timestamp = String.valueOf(new Date().getTime());
        int initPackageNo = 10000;
        Map<String, String> packageNoMap = new HashMap<>();
        for (OtdOrderSo order : orderList) {
            //车配置
            String packageCode = StringUtils.isEmpty(order.getCustomPackCode()) ? "" : order.getCustomPackCode();
            // 产品编码 + 选装包
            String key = order.getProductCode() + packageCode;

            //// 组装选装包、选装包配置接口对象
            // 判断是否已添加过该选装包
            if (packageNoMap.get(key) == null) {
//                String packageNo = new Date().getTime() + "";
                initPackageNo++;
                packageNoMap.put(key, timestamp + initPackageNo);

                //// ============1.选装包
                String[] packageCodes = packageCode.split(",");
                for (String code : packageCodes) {
                    if (!StringUtils.isEmpty(code)) {
                        OtdOptionVO packageVO = new OtdOptionVO();
                        packageVO.setPackage_no(timestamp + initPackageNo);
                        packageVO.setOption_code(code);
                        packageVO.setCar_model(order.getCatalogCode());
                        packages.add(packageVO);
                    }
                }

                //// =======2.工程配置
                /////// 根据约束关系调整默认工程配置 ///////
                // 单车默认配置MAP,<key:特征族,value:特征值>
                Map<String, String> configMap = biz2baseVehicleConfigDubboService
                    .loadEngineeringConfigByVehicleCode(order.getCatalogCode(), order.getColorCodeIn(),
                        order.getColorCodeOut(), packageCode, allConfigMap);
                List<VehicleConfigConstraint> constraintList = constraintsMap.get(order.getModelCode());
                if(!CollectionUtils.isEmpty(constraintList)){
                    for (VehicleConfigConstraint constraint : constraintList) {
                        constraint.setIsProcess(0);
                    }
                    configConstraintService.replaceConfig(constraintList, configMap, allConfigMap);
                }
                List<OtdModelVO> modelVOS = OtdModelVO
                    .createModelVO(configMap, packageNoMap.get(key), order.getCatalogCode());
                options.addAll(modelVOS);
            }



            // 接口类型位I 新增
            if ("I".equals(order.getInterfaceType())) {
                //通过批售单匹配客户订单
                if (!CollectionUtils.isEmpty(customerMap)) {
                    String productCustomCode = order.getProductCode() + (StringUtils.isEmpty(order.getCustomPackCode()) ? ""
                        : order.getCustomPackCode());
                    List<String> customerList = customerMap.get(productCustomCode);
                    if (!CollectionUtils.isEmpty(customerList)) {
                        // 客户订单号
                        order.setCusOrderNo(customerList.get(0));
                        customerList.remove(0);
                        customerMap.put(productCustomCode, customerList);
                    }
                }

                // 首次下发时间
                order.setSendDate(new Date());

                // 新增车辆下线信息 VEHICLE_TURN_STATE_01DSC生产计划
                VehicleOffline car = new VehicleOffline();
                car.setZordNo(order.getPlanNo());
                car.setZwerks(order.getWorks());
                car.setCarType(order.getOrderType());// 车辆类型
                car.setProductCode(order.getProductCode());
                car.setCustomPackCode(order.getCustomPackCode());
                car.setCarState(DictConstant.VEHICLE_TURN_STATE_01DSC);//生产计划
                car.setCreateBy("生产计划下发");
                carService.save(car);
            } else if ("U".equals(order.getInterfaceType())) {
                //U 更新
                VehicleOffline car = carService.selectCarByPlanNo(order.getPlanNo());
                // 更新车辆下线表
                car.setProductCode(order.getProductCode());
                car.setCustomPackCode(order.getCustomPackCode());
                carService.updateById(car);
            } else if ("D".equals(order.getInterfaceType())) {
                // D 删除车辆信息
                carService.removeVehicleCarByPlanNo(order.getPlanNo());
            }

            //// ============3.创建接口订单对象
            orders.add(createWeekPlanVO(order, packageNoMap.get(key)));
            ////  ============4.修改SO计划状态
            order.setUpdateBy("SO订单下发");
            order.setUpdateTime(new Date());
            order.setSapState("W");//待反馈
        }

        // 批量更新接口状态、操作人、操作时间
        updateBatchById(orderList);

        ////  ============5. 周计划接口发送对象转JSON字符串
        WeekPlanDataVO dataVO = new WeekPlanDataVO();
        dataVO.setOptions(packages);
        dataVO.setPackages(options);
        dataVO.setOrders(orders);

        String json = JSONObject.toJSONString(dataVO);
        logger.debug("生成周计划接口JSON：" + json);
        return json;
    }

    /**
     * 创建接口订单对象
     *
     * @param order SO订单
     * @return 接口订单对象
     */
    private WeekPlanVO createWeekPlanVO(OtdOrderSo order,String packageNo) {
        WeekPlanVO data = new WeekPlanVO();
        data.setPlanno(order.getPlanNo());// 计划号
        data.setCar_limit_state(order.getCarLimitState().toString());
        data.setCar_limit_reason(order.getCarLimitReason() == null ? "" : order.getCarLimitReason().toString());
        data.setCar_model(order.getCatalogCode());
        data.setCar_name(order.getCarName());
        data.setDealer_no(order.getDealerNo());
        data.setIndicator(order.getInterfaceType());
        data.setLock_flag(order.getLockFlag());
        data.setOrder_date(DateUtil.format(new Date(), "yyyyMMdd"));
        data.setOrder_no(order.getCusOrderNo());//客户订单号
        data.setRequest_date(DateUtil.format(order.getDemandDate(), "yyyyMMdd"));//排程需求日期
        data.setOrder_type(order.getOrderType());
        data.setQty("1");
        data.setPriority(order.getPriority());
        data.setProject_flag(order.getProjectCarMark());//项目用车标记
        data.setVehicle_code(order.getSeriesCode());//车系
        data.setWerks(order.getWorks());
        data.setZextcolor(order.getColorCodeOut());// 外饰色
        data.setZinttrim(order.getColorCodeIn());// 内饰色
        data.setPackage_no(packageNo);// 对应配置list
//        "订单类型  INVE 国内商品车 EXVE 海外商品车 PRVE 项目车
        if ("PRVE".equals(order.getOrderType())) {
            // 项目车
            data.setZobl1("AS99");
        } else {
            data.setZobl1("AS10");
        }
        return data;
    }


    /**
     * 已匹配零售订单且未配车的 订货单
     * @return key:产品编号加选装包  value:List<客户订单号>
     */
    private Map<String,List<String>> createWaitMatchOrder(){
        // key:产品编号加选装包  value:List<客户订单号>
        Map<String, List<String>> map = new HashMap<>();

        //查询已匹配零售订单且未配车的 订货单
        List<CustomerOrderMatchVO> orderList = orderService.queryCustomerOrderMatchVO();
        if(CollectionUtils.isEmpty(orderList)){
            return null;
        }
        orderList.forEach(data -> {
            List<String> list = map.get(data.getProductCustomCode());
            if( CollectionUtils.isEmpty(list)){
                list = new ArrayList<>();
            }
            list.add(data.getCustomOrderNo());
            map.put(data.getProductCustomCode(),list);
        });
        return map;
    }

}
